package ai.people.core.grpc.handler;

import ai.people.core.grpc.lib.error.Error;
import ai.people.netmon.framework.exception.enums.AuthExceptionEnum;
import ai.people.netmon.framework.exception.enums.CommonEnum;
import ai.people.netmon.framework.model.response.Result;
import ai.people.netmon.framework.utils.ResultUtil;
import io.grpc.Metadata;
import io.grpc.Status;
import io.grpc.StatusRuntimeException;
import io.grpc.protobuf.ProtoUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.Objects;

/**
 * @author yuanqinglong
 * @date 2022/6/5 19:31
 */
@Order(2)
@RestControllerAdvice
public class GrpcExceptionHandler {


    Logger log = LoggerFactory.getLogger(GrpcExceptionHandler.class);

    /**
     * 状态运行时异常
     *
     * @param statusRuntimeException 状态运行时异常
     * @return {@link Result}<{@link T}>
     */
    @ExceptionHandler(StatusRuntimeException.class)
    public <T> Result<T> statusRuntimeException(StatusRuntimeException statusRuntimeException) {
        //记录日志
        log.error("statusRuntimeException exception:", statusRuntimeException);
        Status status = statusRuntimeException.getStatus();
        if (Objects.equals(Status.UNAUTHENTICATED.getCode(), status.getCode()) || Objects.equals(Status.PERMISSION_DENIED.getCode(), status.getCode())) {
            return ResultUtil.error(AuthExceptionEnum.INSUFFICIENT_PERMISSIONS);
        }
        if (Objects.equals(Status.UNAVAILABLE.getCode(), status.getCode())) {
            return ResultUtil.error(CommonEnum.SERVICE_IS_STARTING);
        }
        if (Objects.equals(Status.UNKNOWN.getCode(), status.getCode())) {
            return ResultUtil.error(CommonEnum.SERVICE_IS_STARTING);
        }
        if (Objects.equals(Status.FAILED_PRECONDITION.getCode(), status.getCode())) {
            Metadata metadata = statusRuntimeException.getTrailers();
            Error error = metadata.get(ProtoUtils.keyForProto(Error.getDefaultInstance()));
            if (Objects.nonNull(error) && !StringUtils.isEmpty(error.getMessage())) {
                return ResultUtil.error(error.getCode(), error.getMessage());
            }
        }
        return ResultUtil.error(CommonEnum.SERVER_ERROR);
    }


}
